<?php

/**
 * Support functions for image handling
 * 
 * @version $Id: wok-imager-resize.php 4 2008-11-06 09:53:56Z marcw@pobox.com $
 * @author Marc Worrell
 * @copyright 2008 Marc Worrell
 * 
 * The MIT License
 * 
 * Copyright (c) 2008 Marc Worrell
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */


/**
 * Make a new img tag referring to the image with the correct dimensions.
 * When the image with the correct dimensions does not exist, then create it.
 *
 * @param string img	image element to be replaced
 * @param string uri	uri of the src in the image element
 * @param string file	file referred to by the uri
 * @param string home	home uri of this blog (get_bloginfo('home'))
 * @param string check_modified	set when we should check the modification time of the cache entry
 */
function wok_imager_resize ( $img, $uri, $file, $home, $check_modified )
{
	// Fetch width, height and filter parameters (if present)
	$ps = array('width','height','filter');
	foreach ($ps as $p)
	{
		if (strpos($img, $p) && preg_match("/$p=['\"](.*)['\"]/isU", $img, $ms))
		{
			$$p = $ms[1];
			if (!$$p)
			{
				$$p = null;
			}
		}
		else
		{
			$$p = null;
		}
	}

	if (	($width && $height && !$filter && strpos($img, "-${width}x$height."))
		||	($width  && !is_numeric($width))
		||	($height && !is_numeric($height)))
	{
		// Nothing to do, assume that the image is the correct size
		$img_new = $img;
	}
	else
	{
		// Something to do, either a different size or a filter is applied
		if (strncmp(ABSPATH, $file, strlen(ABSPATH)) == 0)
		{
			$file_rel = substr($file, strlen(ABSPATH));
		}
		else
		{
			$file_rel = $file; 
		}

		$file_rel = str_replace('wp-content/uploads/', '', $file_rel);
		$dir      = ABSPATH . 'wp-content/uploads/wok-imager/'.$file_rel;
		$file_new = $dir.'/'.md5("$file|$width|$height|$filter").'.jpg';
		$error    = false;
		
		// 1. Determine the target image file and check if it is there (then ready)
		if (!@is_dir($dir))
		{
			@mkdir($dir, 0777, true);
		}
		
		// Check modification time of cached file against the original image file
		if ($check_modified && @is_file($file_new) && filemtime($file_new) < filemtime($file))
		{
			unlink($file_new);
			unlink($file_new.'.tag');
		}
		
		if (!@is_file($file_new.'.tag') && @is_dir($dir))
		{
			// 2. Fetch the source image size and orientation
			$info      = wok_imager_info($file);

			// 3. Normalise the filter parameters
			if (!empty($filter))
			{
				$filter = explode(',', $filter);
			}
			else
			{
				$filter = array();
			}
			$filter_pars = array();
			_imager_normalise_filter($filter, $filter_pars);

			// 4. Calculate the width, height and crop parameters
			list($resize_width, $resize_height, $crop) = _imager_calc_size($width, $height, $info['width'], $info['height'], $info['mime'], $filter, $filter_pars, $info['orientation']);

			// When the image will be cropped, use the width and the height of the resulting image
			// only if the width or height are bigger than the cropped one
			if (is_array($crop))
			{
				// left, top, width, height
				$preview_width  = $crop[2];
				$preview_height = $crop[3];
			}
			else
			{
				$preview_width  = $resize_width;
				$preview_height = $resize_height;
			}

			// 5. Obtain resize lock, we don't want a slamdunk of resizers active
			$lock_file = ABSPATH.'wp-content/uploads/wok-imager/lock';
			$fh        = fopen($lock_file, 'w+');

			if ($fh)
			{
				if (flock($fh, LOCK_EX))
				{
					if (!@is_file($file_new))
					{
						// 6. Resize the image
						if (!_imager_resize_file($file, $info['mime'], $resize_width, $resize_height, $crop, $filter, $info['orientation'], 'image/jpeg', $file_new))
						{
							// Serve original file, something went wrong during resizing
							copy($file, $file_new);
						}
					}
				}
				else
				{
					$error = true;
				}

				// 7. Rebuild the image tag, set the correct width and height, remove the filter parameter
				$uri_new = $home . '/' . substr($file_new, strlen(ABSPATH));
				$img_tag = "<img width='$preview_width' height='$preview_height' src='$uri_new' ";

				file_put_contents($file_new.'.img.t', $img_tag);
				@unlink($file_new.'.img');
				rename($file_new.'.img.t', $file_new.'.tag');

				// 8. Release the resize lock
				fclose($fh);
			}
		}

		if (!$error)
		{
			$img_tag = file_get_contents($file_new.'.tag');
			$img_new = preg_replace('/(width|height|filter|src)=[\'"].*[\'"]/isU', '', $img);
			$img_new = $img_tag . substr($img_new, 4);
		}
		else
		{
			// Something went wrong, let's try it another time, for now serve the old img element/file
			$img_new = $img;
		}
	}
	return $img_new;
}


/**
 * Extract information from an image file.
 *
 * @param string file
 * @return array(mime, width, height, orientation), false on an error
 */
function wok_imager_info ( $file )
{
	$size = @getimagesize($file);
	if (is_array($size))
	{
		$ret           = array();
		$ret['width']  = $size[0];
		$ret['height'] = $size[1];
		$ret['mime']   = $size['mime'];

		if ($ret['mime'] == 'image/jpeg' || $ret['mime'] == 'image/tiff')
		{
			$exif = @exif_read_data($file);

	        // Check image orientation
	        if (is_array($exif) && array_key_exists('Orientation', $exif))
	        {
	        	// Check if this is the original image and that the exif is not part of a resized
	        	// image that has been rotated already (before uploading)
	        	//
				// Assume that the camera is taking non-square images...

				$orientation = @min(@max(@intval($exif['Orientation']),1),8);
				if ($orientation > 1)
				{
					$landscape = $size[0] > $size[1];

					if (!empty($exif['ExifImageWidth']))
					{
						$exif_width = $exif['ExifImageWidth'];
					}			
					else if (!empty($exif['COMPUTED']['Width']))
					{
						$exif_width = $exif['COMPUTED']['Width'];
					}
					else
					{
						$exif_width = false;
					}
					if (!empty($exif['ExifImageHeight']))
					{
						$exif_height = $exif['ExifImageHeight'];
					}			
					else if (!empty($exif['COMPUTED']['Height']))
					{
						$exif_height = $exif['COMPUTED']['Height'];
					}
					else
					{
						$exif_height = false;
					}

					if (!empty($exif_width) && !empty($exif_height))
					{
						if ($landscape && $exif_width < $exif_height)
						{
							// The received image is landscape, but the exif describes a portrait orientated image
							// We assume that the rotations have been done already
							$orientation = 1;
						}
						else if (!$landscape && $exif_width > $exif_height)
						{
							// The received image is portrait, but the exif describes a landscape orientated image.
							// We assume that the rotations have been done already
							$orientation = 1;
						}
					}
				}
			}
			else
			{
				$orientation = 1;
			}
		}
		else
		{
			$orientation = 1;
		}
		$ret['orientation'] = $orientation;
	}
	else
	{
		$ret = false;
	}
	return $ret;
	
}


/**
 * Resize the an imagefile to the given size
 * 
 * @param string	file		 file to be resized
 * @param string	mime		 mime type of blob
 * @param int		width		 target width
 * @param int		height		 target height
 * @param array		crop		 crop info
 * @param array 	filter		 image filter options (grayscale) etc.
 * @param int		orientation  orientation from the exif of the image
 * @param string	mime_resize	 mime type of resized image
 * @param string	outfile	 	 outfilename
 * @return boolean
 */
function _imager_resize_file ( $file, $mime, $width, $height, $crop, $filter, $orientation, $mime_resize, $outfile )
{
	// GD library
	if (function_exists('imagecreatefromstring'))
	{
		$success = _imager_resize_gd($file, $mime, $width, $height, $crop, $filter, $orientation, $mime_resize, $outfile);
	}
	else
	{
		trigger_error('image resizer needs GD, but GD is not available', E_USER_WARNING);
		$success = false;
	}
	return $success;
}


/**
 * Resize the image using the gd library
 * 
 * @param $file		 	file to be resized
 * @param $mime		 	mime type of input file
 * @param $width		width of resized image
 * @param $height		height of resized image
 * @param $crop		 	crop of image
 * @param $filter		optional filters
 * @param $orientation  orientation of the image
 * @param $mime_resize	output file mime type
 * @param $outfile		output file
 * @return boolean
 */
function _imager_resize_gd ( $file, $mime, $width, $height, $crop, $filter, $orientation, $mime_resize, $outfile )
{
	// 1. Read the image
	switch ($mime)
	{
	case 'image/gif':
		$im_blob = imagecreatefromgif($file);
		break;
	case 'image/jpeg':
		$im_blob = imagecreatefromjpeg($file); 
		break;
	case 'image/png':
		$im_blob = imagecreatefrompng($file);
		break;
	case 'image/x-ms-bmp':
	case 'image/bmp':
		$im_blob = imagecreatefromwbmp($file);
		break;
	default:
		return false;
	}

	if ($im_blob === false)
	{
		return false;
	}

	// First correct the orientation (as found in the EXIF information)
	switch ($orientation)
	{
	case 2:
		$im_f		= _image_gd_flip($im_blob);
		imagedestroy($im_blob);
		$im_blob	= $im_f;
		break;
	case 3:
		$im_f		= imagerotate($im_blob, 180, 0);
		imagedestroy($im_blob);
		$im_blob	= $im_f;
		break;
	case 4:
		$im_f		= _image_gd_flop($im_blob);
		imagedestroy($im_blob);
		$im_blob	= $im_f;
		break;
	case 5:
		$im_f		= _image_gd_flip($im_blob);
		imagedestroy($im_blob);
		$im_blob	= imagerotate($im_f, 270, 0);
		imagedestroy($im_f);
		break;
	case 6:
		$im_f		= imagerotate($im_blob, 270, 0);
		imagedestroy($im_blob);
		$im_blob	= $im_f;
		break;
	case 7:
		$im_f		= _image_gd_flop($im_blob);
		imagedestroy($im_blob);
		$im_blob	= imagerotate($im_f, 90, 0);
		imagedestroy($im_f);
		break;
	case 8:
		$im_f		= imagerotate($im_blob, 90, 0);
		imagedestroy($im_blob);
		$im_blob	= $im_f;
		break;
	default:
		break;
	}
	
	// 2. resize to width / height
	
	// See if we have to crop the image
	$use_crop = false;
	foreach ($filter as $f)
	{
		if (strncasecmp($f, 'crop', 4) == 0)
		{
			$use_crop = true;
		}
	}
	
	if (!$use_crop)
	{
		$src_x	= 0;
		$src_y	= 0;
		$src_w	= imagesx($im_blob);
		$src_h	= imagesy($im_blob);
		$dst_w	= $width;
		$dst_h	= $height;
	}
	else
	{
		$im_w	= imagesx($im_blob);
		$im_h	= imagesy($im_blob);
		
		$w_rsz	= $im_w / $width;
		$h_rsz	= $im_h / $height;
		
		$dst_w	= $crop[2];
		$dst_h	= $crop[3];
		
		$src_w	= round($dst_w * $w_rsz);
		$src_h	= round($dst_h * $h_rsz);
		$src_x	= round($crop[0] * $w_rsz);
		$src_y	= round($crop[1] * $h_rsz);
	}
	$im = imagecreatetruecolor($dst_w, $dst_h);
	imagecopyresampled($im, $im_blob, 0, 0, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
	imagedestroy($im_blob);
	
	// Apply the effects
	$blur            = false;
	$q               = false;
	$has_imagefilter = function_exists('imagefilter');

	foreach ($filter as $f)
	{
		if (strpos($f, '='))
		{
			list($f,$p) = explode('=', $f, 2);
			$p = explode(':', $p);
		}
		else
		{
			$p = false;
		}
		
		switch ($f)
		{
		case 'crop':
		case 'size':
		case 'scale':
			break;
		case 'gray':
		case 'grayscale':
			_imager_gd_grayscale($im);
			break;
		case 'flip':
			$im_f = _imager_gd_flip($im);
			imagedestroy($im);
			$im  = $im_f;
			break;
		case 'flop':
			$im_f = _imager_gd_flop($im);
			imagedestroy($im);
			$im  = $im_f;
			break;
		case 'q':
			// Quality
			if ($p)
			{
				$q = max(@intval($p[0]), 1);
			}
			break;
		case 'blur':
			if ($has_imagefilter)
			{
				imagefilter($im, IMG_FILTER_GAUSSIAN_BLUR);
				$blur = true;
			}
			break;
		case 'smooth':
			if ($has_imagefilter)
			{
				imagefilter($im, IMG_FILTER_SMOOTH, $p ? $p[0] : 6);
				$blur = true;
			}
			break;
		case 'bright':
		case 'brightness':
			if ($has_imagefilter)
			{
				imagefilter($im, IMG_FILTER_BRIGHTNESS, $p ? $p[0] : 50);
			}
			break;
		case 'contrast':
			if ($has_imagefilter)
			{
				imagefilter($im, IMG_FILTER_CONTRAST, $p ? $p[0] : -10);
			}
			break;
		case 'sepia':
			if ($has_imagefilter)
			{
				imagefilter($im, IMG_FILTER_GRAYSCALE);
				imagefilter($im, IMG_FILTER_COLORIZE, 100, 50, 0);			
			}
			break;
		case 'colorize':
			if ($has_imagefilter && $p)
			{
				imagefilter($im, IMG_FILTER_COLORIZE, $p[0], $p[1], $p[2]);			
			}
			break;
		case 'negate':
			if ($has_imagefilter)
			{
				imagefilter($im, IMG_FILTER_NEGATE);
			}
			break;
		default:
			// Find the filter in the plugin/image directory of anyMeta or the product
			$c = false;
			_imager_plugin($f, $im, $dst_w, $dst_h, $p);
			break;
		}
	}

	// Sharpen the image to compensate for jpeg encoding and resizing softness
	if ($has_imagefilter && !$blur && $width < 400 && $height < 400) 
	{
		imagefilter($im, IMG_FILTER_CONTRAST, -5);
	}

	// Output quality (in case of jpeg)
	if (!$q)
	{
		$q = _imager_quality($width, $height);
	}
	
	// Create the image file and return
	switch ($mime_resize)
	{
	case 'image/png':
		imagepng($im, $outfile.'.t');
		break;
	case 'image/gif':
		imagegif($im, $outfile.'.t');
		break;
	case 'image/jpeg':
	default:
		imagejpeg($im, $outfile.'.t', $q);
		break;
	}
	imagedestroy($im);
	
	// Make the output file creation atomic
	@unlink($outfile);
	rename($outfile.'.t', $outfile);
	return true;
}



/**
 * Return the quality of the jpeg compression to be used for the image
 * smaller images are normally less compressed
 * 
 * @param $width		width of the image
 * @param $height		height of the image
 * @return int		quality for jpeg compression
 */
function _imager_quality ( $width, $height )
{
	$q   = 50;
	$pix = $width * $height;
	
	// Smaller than 300x300 will have better quality
	if ($pix > 0)
	{
		$q_s = 80;

		// 100x100 has max quality
		if ($pix < 10000)
		{
			$q = $q_s;
		}
		else if ($pix < 90000)
		{
			$q += ($pix - 10000) * ($q_s - $q) / 80000;
		}
	}
	return ceil($q);
}



/**
 * Changes the image to grayscale
 * 
 * by Mark Barba
 * http://nl2.php.net/manual/en/function.imagecopymergegray.php
 * 
 * @param $im			the image to change
 * @return void
 */
function _imager_gd_grayscale ( $im )
{
	if (function_exists('imagefilter'))
	{
		imagefilter($im, IMG_FILTER_GRAYSCALE);
	}
	else
	{
		$w = imagesx($im);
		$h = imagesy($im);
		for ($y = 0; $y <$h; $y++) 
		{ 
			for ($x = 0; $x <$w; $x++) 
			{ 
				$rgb	= imagecolorat($im, $x, $y);
				$red	= ($rgb >> 16) & 255;
				$green	= ($rgb >> 8)  & 255;
				$blue	= $rgb & 255;
			
				$gray	= round(0.299*$red + 0.587*$green + 0.114*$blue);
			
				// shift gray level to the left
				$grayR = $gray << 16;	// R: red
				$grayG = $gray << 8;	// G: green
				$grayB = $gray;			// B: blue

				// OR operation to compute gray value
				$grayColor = $grayR | $grayG | $grayB;
			
				// set the pixel color
				imagesetpixel($im, $x, $y, $grayColor);
				imagecolorallocate($im, $gray, $gray, $gray);
			}
		}
	}
}


/**
 * Flips an image
 * 
 * by andreaskalsch at gmx dot de
 * http://nl3.php.net/gd
 * 
 * @param resource im
 * @return resource new im
 */
function _imager_gd_flip ( $im )
{
	$x_i = imagesx($im);
	$y_i = imagesy($im);
	
	$im_ = imagecreatetruecolor($x_i, $y_i);
	for ($x = 0; $x < $x_i; $x++)
	{
		for ($y = 0; $y < $y_i; $y++)
		{
			imagecopy($im_, $im, $x_i - $x - 1, $y, $x, $y, 1, 1);
		}
	}
	return $im_;
}


/**
 * Flops an image (vertical flip)
 * 
 * by andreaskalsch at gmx dot de
 * http://nl3.php.net/gd
 * 
 * @param resource im
 * @return resource	new im
 */
function _imager_gd_flop ( $im )
{
	$x_i = imagesx($im);
	$y_i = imagesy($im);
	
	$im_ = imagecreatetruecolor($x_i, $y_i);
	for ($x = 0; $x < $x_i; $x++)
	{
		for ($y = 0; $y < $y_i; $y++)
		{
			imagecopy($im_, $im, $x, $y_i - $y - 1, $x, $y, 1, 1);
		}
	}
	return $im_;
}



/**
 * Apply the filter on either the image magick command line or the gd image given.
 * 
 * @param string	f		image filter to be applied
 * @param GD		&imgd	GD image (might be empty)
 * @param int 		width
 * @param int 		height
 * @param array     filter parameters
 * @return boolean	filter applied or not
 */
function _imager_plugin ( $f, &$imgd, $width, $height, $parms )
{
	$file = preg_replace('[^a-zA-Z0-9\.\-]', '', $f);
	if (!empty($f))
	{
		$path = dirname(__FILE__) . '/imager-plugin/' . $file . '.php';
		if (@is_file($path) && @is_readable($path))
		{
			require_once $path;
			
			$func = 'imager_' . $f;
			if (function_exists($func))
			{
				$ret = $func($imgd, $width, $height, $parms);
			}
			else
			{
				$ret = false;
			}
		}
		else
		{
			$ret = false;
		}
	}
	else
	{
		$ret = false;
	}
	return $ret;
}


/**
 * Determine the correct extension of the target file
 * this function can be used in combination with the wok_imager_resize
 * function.
 * 
 * Losless formats will be converted to .png when the target size is
 * less than 10.000 pixels (approx 100x100).
 * 
 * @param string mime	mime type of source image
 * @param int width		target width
 * @param int height	target height
 * @return string		file extension (eg ".jpg")
 */
function _imager_resize_extension ( $mime, $width, $height )
{
	// When more than 10.000 pixels, use JPEG compression
	//
	if ($width * $height <= 10000)
	{
		switch ($mime)
		{
		case 'image/tiff':
		case 'image/png':
		case 'image/gif':
		case 'image/x-ms-bmp':
		case 'image/bmp':
			$e = '.png';
			break;
		default:
			$e = '.jpg';
			break;
		}
	}
	else
	{
		$e = '.jpg';
	}
	return $e;
}


/**
 * Cleans up and ordens the filter array in a standard way that can be used
 * for the resize scripts.
 * 
 * @param array &filter		filter array
 * @param array &pars		parameters of extracted commands
 * @return void
 */
function _imager_normalise_filter ( &$filter, &$pars )
{
	$filter1 = array();
	if (is_array($filter))
	{
		foreach ($filter as $f)
		{
			$f = strtolower(trim($f));
			if (strncasecmp($f, 'crop', 4) == 0)
			{
				// Extract the crop parameters
				$c['v'] = 'c';
				$c['h'] = 'c';
				if (strlen($f) >= 6)
				{
					$c[substr($f, 4, 1)] = substr($f, 5, 1);
				}
				if (strlen($f) >= 8)
				{
					$c[substr($f, 6, 1)] = substr($f, 7, 1);
				}
				$pars['crop'] = $c;
				$filter1[]    = 'crop';
			}
			else if (!empty($f))
			{
				$filter1[] = $f;
			}
		}
	}
	$filter = $filter1;
}

/**
 * Calculate the width and the height for the resize function.
 * Also returns an optional crop width and height (false when not needed)
 * 
 * @param int $width			requested width
 * @param int $height			requested height
 * @param int $width_sz			width original
 * @param int $height_sz		height original
 * @param string $mime			mime type of original file
 * @param array $filter			filter function to be used for scaling
 * @param array $filter_pars	filter parameters extracted by normalise_filter()
 * @param int $orientation		Exif orientation flag (1 = normal)
 * @return array list($resize_width, $resize_height, $crop_pars)
 */
function _imager_calc_size ( $width, $height, $width_sz, $height_sz, $mime, $filter, $filter_pars, $orientation )
{
	if ($orientation >= 5)
	{
		// swap the width/height of the original image
		$t         = $width_sz;
		$width_sz  = $height_sz;
		$height_sz = $t;
	}

	// Per default: no crop
	$crop = false;
	
	// Extract the filter options
	if (is_string($filter))
	{
		$filter = explode(',', $filter);
	}
	else if (!is_array($filter))
	{
		$filter = array('scale');
	}
	
	// prevent division by zero
	if ($height_sz <= 0)
	{
		$height_sz = 1;
	}
	if ($width_sz <= 0)
	{
		$width_sz = 1;
	}

	// See if we are allowed to scale the image up
	$scaleup = (in_array('scale', $filter) || in_array('size', $filter) || isset($filter_pars['crop']));

	if (is_null($width) && is_null($height))
	{
		// No size requested, use the size of the original image
		$width	= $width_sz;
		$height = $height_sz;
	}	
	else if (!is_null($width) || !is_null($height))
	{
		if (is_null($width))
		{
			$width = ($width_sz / $height_sz) * $height;
		}
		else if (is_null($height))
		{
			$height = ($height_sz / $width_sz) * $width;
		}
		else if (!in_array('size', $filter))
		{
			// prevent division by zero
			if ($height <= 0)
			{
				$height = 1;
			}
			
			$aspect_sz = $width_sz / $height_sz;
			$aspect    = $width / $height;
			
			if (isset($filter_pars['crop']))
			{
				// When we are doing a crop then we have to calculate the
				// maximum inner bounding box, and not the maximum outer 
				// bounding box for the image
				//
				if ($aspect > $aspect_sz)
				{
					// width is the larger one
					$height0 = $width / $aspect_sz;
					$width0  = $width;
				}
				else
				{
					// height is the larger one
					$width0  = $aspect_sz * $height;
					$height0 = $height;
				}

				$crop_left = 0;
				$crop_top  = 0;

				switch ($filter_pars['crop']['h'])
				{
				case 'c':  $crop_left = floor(($width0 - $width) / 2); break;
				case 'r':  $crop_left = floor($width0 - $width);       break;
				}

				switch ($filter_pars['crop']['v'])
				{
				case 'c':  $crop_top  = floor(($height0 - $height) / 2); break;
				case 'b':  $crop_top  = floor($height0 - $height);       break;
				}

				$crop   = array($crop_left, $crop_top, $width, $height);
				$width  = $width0;
				$height = $height0;
			}
			else
			{
				if ($aspect > $aspect_sz)
				{
					// height is the smaller one
					$width = $aspect_sz * $height;
				}
				else
				{
					// width is the smaller one
					$height = $width / $aspect_sz;
				}
			}
		}

		// Prevent scaling up of the image
		if (!$scaleup && ($height > $height_sz || $width > $width_sz))
		{
			$height = ceil($height_sz);
			$width  = ceil($width_sz);
		}

		$width  = ceil($width);
		$height = ceil($height);
	}
	else 
	{
		// Return the size of the original
		$width  = ceil($width_sz);
		$height = ceil($height_sz);
	}

	// Return all dimensions
	return array($width, $height, $crop);
}

/* vi:set ts=4 sts=4 sw=4 binary noeol: */

?>